﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace VersionComparer.Base
{
    public static class ControlExtensions
    {
        /// <summary>
        /// Executes an action in the control thread
        /// </summary>
        /// <param name="control">control</param>
        /// <param name="action">action to execute</param>
        public static void Execute(this Control control, Action action)
        {
            if (control.InvokeRequired)
            {
                control.Invoke((MethodInvoker)delegate()
                {
                    action();
                });
            }
            else
                action();
        }
        /// <summary>
        /// Executes an action in the control thread
        /// </summary>
        /// <typeparam name="T">type of action parameter</typeparam>
        /// <param name="control">control</param>
        /// <param name="action">action to execute</param>
        /// <param name="argument">argument to pass to the action</param>
        public static void Execute<T>(this Control control, Action<T> action , T argument)
        {
            if (control.InvokeRequired)
            {
                control.Invoke((MethodInvoker)delegate()
                {
                    action(argument);
                });
            }
            else
                action(argument);
        }
        /// <summary>
        /// Executes a function in the control thread
        /// </summary>
        /// <typeparam name="T">type of func parameter</typeparam>
        /// <typeparam name="TResult">type of func return</typeparam>
        /// <param name="control">control</param>
        /// <param name="func">function to execute</param>
        /// <param name="argument">argument to pass to the function</param>
        /// <returns>func result</returns>
        public static TResult ExecuteFunc<T, TResult>(this Control control, Func<T, TResult> func, T argument)
        {
            TResult result = default ( TResult );
            if (control.InvokeRequired)
            {
                control.Invoke((MethodInvoker)delegate()
                {
                    result = func(argument);
                });
            }
            else
                result = func(argument);
            return result;
        }
        /// <summary>
        /// Execute an action in the control thread
        /// </summary>
        /// <typeparam name="T1">action first parameter</typeparam>
        /// <typeparam name="T2">action second parameter</typeparam>
        /// <param name="control">control</param>
        /// <param name="action">action to execute</param>
        /// <param name="argument1">action first parameter</param>
        /// <param name="argument2">action second parameter</param>
        public static void Execute<T1, T2>(this Control control, Action<T1, T2> action, T1 argument1, T2 argument2)
        {
            if (control.InvokeRequired)
            {
                control.Invoke((MethodInvoker)delegate()
                {
                    action(argument1,argument2);
                });
            }
            else
                action(argument1, argument2);
        }
    }
}
